using CollabApp.Domain.Entities.Game;

namespace CollabApp.Domain.Services.Game;

/// <summary>
/// 领土管理服务接口
/// 负责管理圈地游戏中的领土系统，包括画线轨迹、领地计算、圈地检测等
/// </summary>
public interface ITerritoryService
{
    /// <summary>
    /// 开始画线
    /// 玩家从己方领地或出生点开始画线
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="startPosition">起始位置</param>
    /// <returns>画线开始结果</returns>
    Task<DrawingStartResult> StartDrawingAsync(Guid gameId, Guid playerId, Position startPosition);

    /// <summary>
    /// 更新画线轨迹
    /// 玩家移动时更新画线轨迹
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="newPosition">新位置</param>
    /// <returns>轨迹更新结果</returns>
    Task<TrailUpdateResult> UpdateTrailAsync(Guid gameId, Guid playerId, Position newPosition);

    /// <summary>
    /// 完成圈地
    /// 当玩家画线回到己方领地时完成圈地
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="endPosition">结束位置</param>
    /// <returns>圈地完成结果</returns>
    Task<TerritoryCompleteResult> CompleteTerritoryAsync(Guid gameId, Guid playerId, Position endPosition);

    /// <summary>
    /// 计算玩家领地面积
    /// 使用多边形面积算法计算玩家当前领地面积
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <returns>领地面积信息</returns>
    Task<TerritoryAreaInfo> CalculatePlayerTerritoryAsync(Guid gameId, Guid playerId);

    /// <summary>
    /// 检查位置是否在玩家领地内
    /// 检查指定位置是否属于某玩家的领地
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="position">检查位置</param>
    /// <param name="playerId">玩家标识（可选）</param>
    /// <returns>领地归属信息</returns>
    Task<TerritoryOwnership> CheckTerritoryOwnershipAsync(Guid gameId, Position position, Guid? playerId = null);

    /// <summary>
    /// 重置玩家领地
    /// 玩家死亡时重置领地到出生点安全区
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <param name="keepPercentage">保留的领地记忆百分比</param>
    /// <returns>重置结果</returns>
    Task<TerritoryResetResult> ResetPlayerTerritoryAsync(Guid gameId, Guid playerId, decimal keepPercentage = 0.2m);

    /// <summary>
    /// 获取地图领土分布
    /// 获取当前游戏中所有玩家的领地分布情况
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <returns>地图领土分布信息</returns>
    Task<MapTerritoryDistribution> GetMapTerritoryDistributionAsync(Guid gameId);

    /// <summary>
    /// 计算领地争夺
    /// 当圈地包围敌方领地时计算争夺结果
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="attackerId">攻击者ID</param>
    /// <param name="newTerritory">新圈定的领地</param>
    /// <returns>争夺结果</returns>
    Task<TerritoryConquestResult> CalculateTerritoryConquestAsync(Guid gameId, Guid attackerId, List<Position> newTerritory);

    /// <summary>
    /// 检查画线长度限制
    /// 检查玩家当前画线长度是否超过限制
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <returns>长度检查结果</returns>
    Task<TrailLengthCheckResult> CheckTrailLengthLimitAsync(Guid gameId, Guid playerId);

    /// <summary>
    /// 应用地图缩圈效果
    /// 游戏最后30秒时应用地图缩圈效果
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="shrinkRadius">缩圈半径</param>
    /// <returns>缩圈应用结果</returns>
    Task<MapShrinkResult> ApplyMapShrinkAsync(Guid gameId, float shrinkRadius);

    /// <summary>
    /// 检查提前结束条件
    /// 检查是否有玩家占领超过70%地图
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <returns>提前结束检查结果</returns>
    Task<EarlyEndCheckResult> CheckEarlyEndConditionAsync(Guid gameId);

    /// <summary>
    /// 获取游戏领地概览
    /// 获取游戏中所有玩家的领地分布和统计信息
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <returns>领地概览结果</returns>
    Task<TerritoryOverviewResult> GetGameTerritoryOverviewAsync(Guid gameId);
}

/// <summary>
/// 领地概览结果
/// </summary>
public class TerritoryOverviewResult
{
    public bool Success { get; set; }
    public Guid GameId { get; set; }
    public DateTime Timestamp { get; set; }
    public float TotalMapArea { get; set; }
    public float ClaimedArea { get; set; }
    public List<PlayerTerritoryStats> PlayerStats { get; set; } = new();
    public List<string> Errors { get; set; } = new();
}

/// <summary>
/// 玩家领地统计
/// </summary>
public class PlayerTerritoryStats
{
    public Guid PlayerId { get; set; }
    public string PlayerName { get; set; } = string.Empty;
    public string PlayerColor { get; set; } = string.Empty;
    public decimal Area { get; set; }
    public decimal Percentage { get; set; }
    public int Rank { get; set; }
    public bool IsAlive { get; set; }
    public Position SpawnPoint { get; set; } = new();
    public List<Position> TerritoryBoundary { get; set; } = new();
}

/// <summary>
/// 画线开始结果
/// </summary>
public class DrawingStartResult
{
    public bool Success { get; set; }
    public Guid TrailId { get; set; }
    public Position StartPosition { get; set; } = new();
    public bool FromSafeArea { get; set; }
    public DateTime StartTime { get; set; } = DateTime.UtcNow;
    public List<string> Messages { get; set; } = new();
    public List<string> Errors { get; set; } = new();
    public string? ErrorMessage { get; set; }
}

/// <summary>
/// 轨迹更新结果
/// </summary>
public class TrailUpdateResult
{
    public bool Success { get; set; }
    public Guid TrailId { get; set; }
    public List<Position> CurrentTrail { get; set; } = new();
    public float TrailLength { get; set; }
    public bool IsNearLimit { get; set; }
    public string? ErrorMessage { get; set; }
}

/// <summary>
/// 圈地完成结果
/// </summary>
public class TerritoryCompleteResult
{
    public bool Success { get; set; }
    public decimal AreaGained { get; set; }
    public decimal NewTotalArea { get; set; }
    public List<Position> NewTerritory { get; set; } = new();
    public List<Guid> ConqueredPlayers { get; set; } = new();
    public decimal ConqueredArea { get; set; }
    public string? ErrorMessage { get; set; }
}

/// <summary>
/// 领地面积信息
/// </summary>
public class TerritoryAreaInfo
{
    public Guid PlayerId { get; set; }
    public decimal CurrentArea { get; set; }
    public decimal MaxHistoryArea { get; set; }
    public decimal AreaPercentage { get; set; }
    public int Rank { get; set; }
    public List<Position> TerritoryBoundary { get; set; } = new();
    public Position Center { get; set; } = new();
}

/// <summary>
/// 领地归属信息
/// </summary>
public class TerritoryOwnership
{
    public bool IsOwned { get; set; }
    public Guid? OwnerId { get; set; }
    public string? OwnerColor { get; set; }
    public bool IsNeutralZone { get; set; }
    public bool IsSpawnArea { get; set; }
    public float DistanceToNearestBoundary { get; set; }
}

/// <summary>
/// 领地重置结果
/// </summary>
public class TerritoryResetResult
{
    public bool Success { get; set; }
    public decimal RemainingArea { get; set; }
    public Position NewSpawnArea { get; set; } = new();
    public decimal LostArea { get; set; }
}

/// <summary>
/// 地图领土分布
/// </summary>
public class MapTerritoryDistribution
{
    public Guid GameId { get; set; }
    public DateTime Timestamp { get; set; }
    public float TotalMapArea { get; set; }
    public float ClaimedArea { get; set; }
    public float NeutralArea { get; set; }
    public List<PlayerTerritoryInfo> PlayerTerritories { get; set; } = new();
    public bool HasDominantPlayer { get; set; }
    public Guid? DominantPlayerId { get; set; }
}

/// <summary>
/// 玩家领土信息
/// </summary>
public class PlayerTerritoryInfo
{
    public Guid PlayerId { get; set; }
    public string PlayerName { get; set; } = string.Empty;
    public string PlayerColor { get; set; } = string.Empty;
    public decimal Area { get; set; }
    public decimal Percentage { get; set; }
    public int Rank { get; set; }
    public List<Position> Territory { get; set; } = new();
    public Position SpawnPoint { get; set; } = new();
    public bool IsDrawing { get; set; }
    public List<Position>? CurrentTrail { get; set; }
}

/// <summary>
/// 领地征服结果
/// </summary>
public class TerritoryConquestResult
{
    public bool Success { get; set; }
    public List<Guid> ConqueredPlayers { get; set; } = new();
    public decimal TotalConqueredArea { get; set; }
    public List<TerritoryConquest> Conquests { get; set; } = new();
    public decimal NewTotalArea { get; set; }
}

/// <summary>
/// 领土征服详情
/// </summary>
public class TerritoryConquest
{
    public Guid ConqueredPlayerId { get; set; }
    public decimal ConqueredArea { get; set; }
    public List<Position> ConqueredTerritory { get; set; } = new();
}

/// <summary>
/// 轨迹长度检查结果
/// </summary>
public class TrailLengthCheckResult
{
    public bool IsWithinLimit { get; set; }
    public float CurrentLength { get; set; }
    public float MaxLength { get; set; }
    public float RemainingLength { get; set; }
    public bool IsNearLimit { get; set; }
}

/// <summary>
/// 地图缩圈结果
/// </summary>
public class MapShrinkResult
{
    public bool Success { get; set; }
    public float NewMapRadius { get; set; }
    public List<Guid> AffectedPlayers { get; set; } = new();
    public decimal TotalAreaLost { get; set; }
    public List<PlayerAreaLoss> PlayerLosses { get; set; } = new();
}

/// <summary>
/// 玩家面积损失
/// </summary>
public class PlayerAreaLoss
{
    public Guid PlayerId { get; set; }
    public decimal AreaLost { get; set; }
    public decimal RemainingArea { get; set; }
}

/// <summary>
/// 提前结束检查结果
/// </summary>
public class EarlyEndCheckResult
{
    public bool CanEndEarly { get; set; }
    public Guid? DominantPlayerId { get; set; }
    public decimal DominantPlayerPercentage { get; set; }
    public EarlyEndReason Reason { get; set; }
}

/// <summary>
/// 提前结束原因
/// </summary>
public enum EarlyEndReason
{
    None,
    DominantPlayer,     // 单一玩家占领70%地图
    LastPlayerStanding, // 只剩一名存活玩家
    TimeExpired        // 时间到
}
